package com.bes.bessdk.utils;

import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.util.List;
import java.util.zip.CRC32;
import java.nio.ByteBuffer;

public class ArrayUtil {
    public static byte[] extractBytes(byte[] data, int start, int length) {
        byte[] bytes = new byte[length];
        System.arraycopy(data, start, bytes, 0, length);
        return bytes;
    }

    public static boolean isEqual(byte[] array_1, byte[] array_2) {
        if (array_1 == null) {
            return array_2 == null;
        }
        if (array_2 == null) {
            return false;
        }
        if (array_1 == array_2) {
            return true;
        }
        if (array_1.length != array_2.length) {
            return false;
        }
        for (int i = 0; i < array_1.length; i++) {
            if (array_1[i] != array_2[i]) {
                return false;
            }
        }
        return true;
    }

    public static boolean contains(byte[] parent, byte[] child) {
        if (parent == null) {
            return child == null;
        }
        if (child == null || child.length == 0) {
            return true;
        }
        if (parent == child) {
            return true;
        }
        return new String(parent).contains(new String(child));
    }

    public static long crc32(byte[] data, int offset, int length) {
        CRC32 crc32 = new CRC32();
        crc32.update(data, offset, length);
        return crc32.getValue();
    }

    public static byte checkSum(byte[] data, int len) {
        byte sum = (byte) 0;
        for (int i = 0; i < len; i++) {
            sum ^= data[i];
        }
        return sum;
    }

    public static String toHex(byte[] data) {
        if(data == null){
            return null;
        }
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            buffer.append(String.format("%02x", data[i])).append(",");
        }
        return buffer.toString();
    }

    public static String toDec(byte[] data) {
        if(data == null){
            return null;
        }
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            buffer.append(String.format("%02d", data[i])).append(",");
        }
        if (buffer.length() > 0) {
            buffer.setLength(buffer.length() - 1);
        }
        return buffer.toString();
    }

    public static String toASCII(byte[] data) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            buffer.append((char)data[i]);
        }
        return buffer.toString();
    }

    public static boolean startsWith(byte[] data, byte[] param) {
        if (data == null) {
            return param == null;
        }
        if (param == null) {
            return true;
        }
        if (data.length < param.length) {
            return false;
        }
        for (int i = 0; i < param.length; i++) {
            if (data[i] != param[i]) {
                return false;
            }
        }
        return true;
    }

    public static boolean endWith(byte[] data, byte[] param) {
        if (data == null) {
            return param == null;
        }
        if (param == null) {
            return true;
        }
        if (data.length < param.length) {
            return false;
        }
        for (int i = 0; i < param.length; i++) {
            if (data[data.length - 1 - i] != param[param.length - 1 - i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 将toHex()16进制字符串转换为byte[]
     *
     * @param str
     * @return
     * add by fanxiaoli 20190102
     */
    public static byte[] toBytes(String str) {
        if(str == null || str.trim().equals("")) {
            return new byte[0];
        }
        str = str.replace(",","");//与toHex函数对应
        if(str == null || str.trim().equals("")) {
            return new byte[0];
        }
        byte[] bytes = new byte[str.length() / 2];
        for(int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }
        return bytes;
    }

    /**
     * 以小端模式将byte[]转成int
     * add by fanxiaoli 20190102
     */
    public static int bytesToIntLittle(byte[] src) {
        int value = 0;
        value = (int) ((src[0] & 0xFF)
                | ((src[1] << 8) & 0xFF00)
                | ((src[2] << 16) & 0xFF0000)
                | ((src[3] << 24) & 0xFF000000));
        return value;
    }

    /*获取如1.1.1.1格式版本号
     * add by fanxiaoli 20190114
     */
    public static String  bytesToVersion(byte[] src) {
        String version = "";
        int[] version_int = new int[4];
        if(src.length==4) {
            for (int i = 0;i<src.length;i++) {
                version_int[i] = (int) (src[i] & 0xff);
                version = version + (String.valueOf(version_int[i]));
                if (i < 3) {
                    version = version + ".";
                }
            }
        }
        return version;
    }

    public static byte[] intToBytesLittle(int value) {
        byte[] src = new byte[4];
        src[3] = (byte) ((value >> 24) & 0xFF);
        src[2] = (byte) ((value >> 16) & 0xFF);
        src[1] = (byte) ((value >> 8) & 0xFF);
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    public static int bytesToShortLittle(byte[] src) {
        int value = 0;
        value = (short) ((src[0] & 0xFF) | ((src[1] << 8) & 0xFF00));
        return value;
    }

    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[len - i -1] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    private static int toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }

    //+++/将byte转换成16进制字符串
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static byte[] int2byte(long res) {
        byte[] targets = new byte[4];
        targets[0] = (byte) (res & 0xff);// 最低位
        targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
        targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
        targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
        return targets;
    }

    public static long getFloat(byte[] b) {
        int accum = 0;
        accum = accum|(b[0] & 0xff) << 0;
        accum = accum|(b[1] & 0xff) << 8;
        accum = accum|(b[2] & 0xff) << 16;
        accum = accum|(b[3] & 0xff) << 24;
        return accum;
    }

    //ota
    public static byte[] bytesSplic(byte[] pt, byte[] l, byte[] magic, byte[] data) {
        byte[] bytes = new byte[pt.length + l.length + magic.length + data.length];
        System.arraycopy(pt, 0, bytes, 0, pt.length);
        System.arraycopy(l, 0, bytes, pt.length, l.length);
        System.arraycopy(magic, 0, bytes, pt.length + l.length, magic.length);
        System.arraycopy(data, 0, bytes, pt.length + l.length + magic.length, data.length);
        return bytes;
    }

    public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){
        byte[] byte_3 = new byte[byte_1.length + byte_2.length];
        System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
        System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
        return byte_3;
    }

    /**
     * 字符串转换成十六进制字符串
     * @param  str 待转换的ASCII字符串
     * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
     */
    public static String str2HexStr(String str)
    {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;

        for (int i = 0; i < bs.length; i++)
        {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            sb.append(',');
        }
        return sb.toString().trim();
    }

    public static String hexStr2Str(String bytes) {
        String hexString = "0123456789abcdef";
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
        //将每2位16进制整数组装成一个字节
        for (int i = 0; i < bytes.length(); i += 2)
            baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1))));
        return new String(baos.toByteArray());
    }

    public static int  getRssiValue(byte data) {
        return  Integer.valueOf(data);
    }

    public static float byte2float(byte[] b) {
        int l;
        int index = 0;
        l = b[index + 0];
        l &= 0xff;
        l |= ((long) b[index + 1] << 8);
        l &= 0xffff;
        l |= ((long) b[index + 2] << 16);
        l &= 0xffffff;
        l |= ((long) b[index + 3] << 24);
        return Float.intBitsToFloat(l);
    }

    public static byte[] float2byte(float f) {
        // 把float转换为byte[]
        int fbit = Float.floatToIntBits(f);

        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (fbit >> (24 - i * 8));
        }
//        // 翻转数组
        int len = b.length;
        // 建立一个与源数组元素类型相同的数组
        byte[] dest = new byte[len];
        // 为了防止修改源数组，将源数组拷贝一份副本
        System.arraycopy(b, 0, dest, 0, len);
        byte temp;
        // 将顺位第i个与倒数第i个交换
        for (int i = 0; i < len / 2; ++i) {
            temp = dest[i];
            dest[i] = dest[len - i - 1];
            dest[len - i - 1] = temp;
        }
        return dest;
    }

    public static short getShort(byte argB1, byte argB2) {
        return (short)((argB1 & 0xFF) | (argB2 << 8));
    }

    public static String div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        double result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
        Log.i("TAG", "sendPacketData: -----div--" + result);
        return  result + "";
        //String value = getTwoDecimal(result).replace(",", ".");
        //return value;
    }

    public static String getTwoDecimal(double num) {
        DecimalFormat dFormat = new DecimalFormat("0.00");
        String yearString = dFormat.format(num);
        return yearString;
    }

    public static int byte2int(byte[] res) {
        int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00); // | 表示安位或
        return targets;
    }

    public static int byte2int2(byte[] res) {
        int targets = (res[0] & 0xff); // | 表示安位或
        return targets;
    }

    public static String byteToBit(byte b) {
        return "" +(byte)((b >> 7) & 0x1) +
                (byte)((b >> 6) & 0x1) +
                (byte)((b >> 5) & 0x1) +
                (byte)((b >> 4) & 0x1) +
                (byte)((b >> 3) & 0x1) +
                (byte)((b >> 2) & 0x1) +
                (byte)((b >> 1) & 0x1) +
                (byte)((b >> 0) & 0x1);
    }

    public static byte bitToByte(String byteStr) {
        int re, len;
        if (null == byteStr) {
            return 0;
        }
        len = byteStr.length();
        if (len != 4 && len != 8) {
            return 0;
        }
        if (len == 8) {// 8 bit处理
            if (byteStr.charAt(0) == '0') {// 正数
                re = Integer.parseInt(byteStr, 2);
            } else {// 负数
                re = Integer.parseInt(byteStr, 2) - 256;
            }
        } else {//4 bit处理
            re = Integer.parseInt(byteStr, 2);
        }
        return (byte) re;
    }

    public static void addObjectIndex(List arr, Object obj, int index) {
        if (arr.size() > index) {
            arr.remove(index);
            arr.add(index, obj);
        }
    }

    public static void resetObjectAtIndex(List arr, int index) {
        if (arr.size() > index) {
            arr.remove(index);
            arr.add(index, null);
        }
    }

    public static byte[] longToBytes2(int value) {
        byte[] src = new byte[4];
        src[3] = (byte) ((value >> 24));
        src[2] = (byte) ((value >> 16) & 0xFF);
        src[1] = (byte) ((value >> 8) & 0xFF);
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    public static byte[] intToBytes2(int value) {
        byte[] src = new byte[2];
        src[1] = (byte) ((value >> 8) & 0xFF);
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    public static short[] bytesToShort(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        short[] shorts = new short[bytes.length / 2];
        ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        return shorts;
    }

    public static byte[] shorts2Bytes(short[] s) {
        byte bLength = 2;
        byte[] buf = new byte[s.length * bLength];
        for (int iLoop = 0; iLoop < s.length; iLoop++) {
            byte[] temp = getBytes(s[iLoop]);
            for (int jLoop = 0; jLoop < bLength; jLoop++) {
                buf[iLoop * bLength + jLoop] = temp[jLoop];
            }
        }
        return buf;
    }

    public static byte[] getBytes(short s) {
        boolean bBigEnding = false;
        byte[] buf = new byte[2];
        if (bBigEnding)
            for (int i = buf.length - 1; i >= 0; i--) {
                buf[i] = (byte) (s & 0x00ff);
                s >>= 8;
            }
        else
            for (int i = 0; i < buf.length; i++) {
                buf[i] = (byte) (s & 0x00ff);
                s >>= 8;
            }
        return buf;
    }

    public static byte[] dataToMD5(byte[] data) {
        byte[] hash;
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
            md.update(data, 0, data.length);
            hash = md.digest();
            return hash;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
	}

    public static byte[] intToBytes3(int value) {
        byte[] src = new byte[1];
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    public static String[] stringToStringArray(String src, int length){
        // 检查参数是否合法
        if(null == src || src.equals("")){
            return null;
        }
        if(length <= 0){
            return null;
        }
        // 获取整个字符串可以被切割成字符子串的个数
        int n = (src.length() + length - 1) / length;
        String[] split = new String[n];
        for(int i = 0; i < n ; i++){
            if(i < (n - 1)){
                split[i] = src.substring(i * length, (i + 1) * length);
            } else {
                split[i] = src.substring(i * length);
            }
        }
        return split;
    }

    public static byte[] convertToByteArray(String[] strings) {
        int totalLength = 0; // 计算所有字符串长度之和

        for (int i = 0; i < strings.length; i++) {
            totalLength += strings[i].getBytes().length;
        }
        ByteBuffer buffer = ByteBuffer.allocate(totalLength); // 创建一个大小合适的字节缓冲区
        for (int i = 0; i < strings.length; i++) {
            String str = strings[i];
            if (!str.isEmpty()) {
                byte[] bytes = str.getBytes(); // 获取每个字符串对应的字节数组
                buffer.put(bytes); // 将字节数组写入到缓冲区
            }
        }
        return buffer.array(); // 返回最终的字节数组结果
    }

//    public static String[] convertToHex(String[] array) {
//        if (array == null || array.length == 0) {
//            return new String[0]; // 返回空数组或者根据需求处理其他情况
//        }
//
//        int length = array.length;
//        String[] hexArray = new String[length];
//
//        for (int i = 0; i < length; i++) {
//            byte[] bytes = array[i].getBytes();
//
//            StringBuilder sb = new StringBuilder();
//            for (byte b : bytes) {
//                sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1));
//            }
//
//            hexArray[i] = sb.toString().toUpperCase();
//        }
//
//        return hexArray;
//    }

    public static String convertToHex(String input) {
        StringBuilder hex = new StringBuilder();
        for (char c : input.toCharArray()) {
            hex.append(Integer.toString((int) c, 16));
        }
        return hex.toString().toUpperCase();
    }

}
